/**
 * Copyright 2010 Tristan Slominski
 *
 * Licensed under the MIT License (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.opensource.org/licenses/mit-license.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.mindash.handlebars.client.views.impl;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.uibinder.client.UiTemplate;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.mindash.handlebars.client.presenters.impl.LoginPresenterImpl;

/**
 * @author "Tristan Slominski"
 * 
 */
public class LoginViewImpl extends DefaultViewImpl {

  public static interface DebugIds {
    public static String loginViewImpl = "loginViewImpl";

    public static String loginErrorLabel = loginViewImpl + "-loginError";
    public static String passwordErrorLabel = loginViewImpl + "-passwordError";
    public static String passwordPasswordTextBox = loginViewImpl + "-password";
    public static String signInButton = loginViewImpl + "-signInButton";
    public static String usernameErrorLabel = loginViewImpl + "-usernameError";
    public static String usernameTextBox = loginViewImpl + "-username";
  }

  @UiTemplate("/ui/LoginViewImpl.ui.xml")
  interface FormBinder extends UiBinder<Widget, LoginViewImpl> {
  }

  private static final FormBinder formBinder = GWT.create(FormBinder.class);

  /* widgets */
  @UiField
  Label loginError;
  @UiField
  PasswordTextBox password;
  @UiField
  Label passwordError;
  @UiField
  Button signInButton;
  @UiField
  TextBox username;
  @UiField
  Label usernameError;

  @Override
  public Widget createAndBind() {
    /*
     * always call bindView() first in order to make sure any "provided" widgets
     * are provided (currently there are none, but it's good practice to do this
     * anyway as a pattern)
     */
    bindView();
    /* we will always use form binder for login view */
    initWidget(formBinder.createAndBindUi(this));
    /*
     * there are some instances which require the presenter to touch the view
     * once all the widgets are ready, postProcessView() call is where the
     * presenter can do that knowing the view is ready (in this case it's not
     * used by the LoginPresenter, but it's good practice to do this anyway as a
     * pattern)
     */
    postProcessView();
    /* set focus on username text box */
    DeferredCommand.addCommand(new Command() {

      @Override
      public void execute() {
        LoginViewImpl.this.username.setFocus(true);
      }

    });
    /* setup debug information for use by Selenium */
    this.ensureDebugId(DebugIds.loginViewImpl);
    loginError.ensureDebugId(DebugIds.loginErrorLabel);
    password.ensureDebugId(DebugIds.passwordPasswordTextBox);
    passwordError.ensureDebugId(DebugIds.passwordErrorLabel);
    signInButton.ensureDebugId(DebugIds.signInButton);
    username.ensureDebugId(DebugIds.usernameTextBox);
    usernameError.ensureDebugId(DebugIds.usernameErrorLabel);
    /* return the view as a widget that is ready to display */
    return this;
  }

  /* Ui Handlers */

  @UiHandler("password")
  public void onPasswordKeyPress(KeyPressEvent event) {
    executeOnSignInIfEnterKey(event);
  }

  @UiHandler("username")
  public void onUsernameKeyPress(KeyPressEvent event) {
    executeOnSignInIfEnterKey(event);
  }

  @UiHandler("signInButton")
  public void onSignInButtonClick(ClickEvent event) {
    executeOnSignIn();
  }

  private void executeOnSignIn() {
    // TODO: not particularly proud how the presenter needs to be cast here
    // (should probably make getPresenter() generic)
    ((LoginPresenterImpl) getPresenter()).onSignIn();
  }

  private void executeOnSignInIfEnterKey(KeyPressEvent event) {
    if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
      executeOnSignIn();
    }
  }

}
